<?php


namespace app\reception\controller;


use app\common\model\QuickApp;
use app\common\model\SignConfig;
use app\common\model\TaskConfig;
use app\common\model\UserBookPoints;
use app\reception\logic\TaskLogic;
use think\Db;

class Task extends Common
{
    protected $middleware = [
        'VerifyAuth' => ['except' => []],
    ];
    private $ubp;

    /**
     * 所有任务
     * @return \think\response\Json
     */
    public function allTasks()
    {
        $type = input('task_type', 0);
        if (!in_array($type, [0, 1, 2])) {
            return errJson('task_type值异常');
        }
        $where[] = ['quick_id', '=', $this->quickAppId];
        if ($this->user->agent_id) {
            $where[] = ['manage_id', '=', $this->user->agent_id];
        } else {
            $where[] = ['manage_id', '=', 0];
        }
        $myTaskData = TaskConfig::where($where)->value('task_data');
        $defaultTemplate = TaskConfig::defaultTemplate($this->quickAppId);
        $myTaskData = json_decode($myTaskData, true);
        $data = [];
        if ($myTaskData) {
            foreach ($defaultTemplate as $k => $v) {
                if (isset($myTaskData[$k])) {
                    $data[$k] = $myTaskData[$k];
                } else {
                    $data[$k] = $v;
                }
            }
        } else {
            $data = $defaultTemplate;
        }
        foreach ($data as $k => $v) {
            if ($type == 1 && in_array($k, ['read', 'pay_give'])) {
                unset($data[$k]);
            } elseif ($type == 2 && in_array($k, ['add_desktop', 'bind_number', 'calendar'])) {
                unset($data[$k]);
            } else {
                if ($v['display'] != 1) {
                    unset($data[$k]);
                } else {
                    if ($k == 'calendar') {
                        $package = request()->header('x-quick-package');
                        $data[$k]['event']['description'] = $data[$k]['event']['description'] . "http://hapjs.org/app/{$package}/pages/main";
                    }
                    $data[$k]['state'] = $this->getTaskState($k, $v);
                }
                unset($data[$k]['display']);
            }
        }
        $data = array_values($this->sortBySortValue($data));
        return sucJson($data);
    }

    /**
     * 获取领取记录对象
     * @return UserBookPoints
     */
    private function getUbp()
    {
        if (!is_object($this->ubp)) {
            $this->ubp = new UserBookPoints();
        }
        return $this->ubp;
    }


    /**
     * 获取任务状态
     * @param $key
     * @param $config
     * @return int
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getTaskState($key, $config)
    {
        if ($key == 'add_desktop') {
            $ubp = $this->getUbp();
            $flat = $ubp->where('uid', $this->uid)->where('give_type', $ubp::add_desktop)->find();
            if ($flat) {
                return 2;
            } else {
                return 1;
            }
        } elseif ($key == 'bind_number') {
            if ($this->user->phone) {
                return 2;
            } else {
                return 1;
            }
        } elseif ($key == 'calendar') {
            $ubp = $this->getUbp();
            $flat = $ubp->where('uid', $this->uid)->where('give_type', $ubp::calendar)->find();
            if ($flat) {
                return 2;
            } else {
                return 1;
            }
        } elseif ($key == 'read') {
            $ubp = $this->getUbp();
            $flat = $ubp->where('uid', $this->uid)->where('give_type', $ubp::read)->where("create_time", '>=', date("Y-m-d 00:00:00"))->find();
            if ($flat) {
                return 2;
            } else {
                $recordTable = "quick_user_read_record_" . date("Ym");
                $readList = Db::table($recordTable)->field("novel_id,count(*) num")
                    ->where("uid", $this->uid)
                    ->where("read_time", ">=", date("Y-m-d 00:00:00"))
                    ->group("novel_id")
                    ->select();
                $novelIds = [];
                foreach ($readList as $k => $v) {
                    if ($v['num'] >= $config['chapter_num']) {
                        $novelIds[] = $v['novel_id'];
                    }
                }
                $res = 0;
                foreach ($novelIds as $nid) {
                    $chapterNoArr = Db::table($recordTable)
                        ->where("uid", $this->uid)
                        ->where("novel_id", $nid)
                        ->where("read_time", ">=", date("Y-m-d 00:00:00"))
                        ->column('chapter_no');
                    $chapterNoArr = array_unique($chapterNoArr);
                    if (count($chapterNoArr) >= $config['chapter_num']) {
                        $res = 1;
                        break;
                    }
                }
                return $res;
            }
        } elseif ($key == 'pay_give') {
            $payCount = Db::table('pay_order')->where("uid", $this->uid)->where("status", 2)->count();
            $ubp = $this->getUbp();
            $ubpCount = $ubp->where('uid', $this->uid)->where('give_type', $ubp::pay_give)->count();
            if ($payCount > $ubpCount) {
                return 1;
            } elseif ($payCount == 0) {
                return 0;
            } else {
                return 2;
            }
        } else {
            return 0;
        }
    }

    /**
     * 按sort重新排序
     * @param $array
     * @return mixed
     */
    private function sortBySortValue($array)
    {
        $sortValues = array_column($array, 'sort');
        array_multisort($sortValues, SORT_ASC, $array);
        return $array;
    }


    /**
     * 获取单个任务
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getTask()
    {
        $params = $this->request->param();
        $result = $this->validate($params, 'app\reception\validate\TaskValidate.getTask');
        if (true !== $result) {
            return errJson($result);
        }
        $key = input('key');
        $task = $this->getTaskInfo($key);
        if ($task) {
            return sucJson($task);
        }
        return errJson('无对应任务');
    }

    /**
     * 领取任务奖励
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function claimRewards()
    {
        $task_key = input('task_key');
        $params = $this->request->param();
        $result = $this->validate($params, 'app\reception\validate\TaskValidate.claimRewards');
        if (true !== $result) {
            return errJson($result);
        }
        $task = $this->getTaskInfo($task_key);
        if (!$task) {
            return errJson('任务不存在，领取失败');
        }
        if ($task['state'] == 1) {
            $ubp = $this->getUbp();
            if ($task_key == 'calendar') {
                $giveType = $ubp::calendar;
            } elseif ($task_key == 'pay_give') {
                $giveType = $ubp::pay_give;
            } elseif ($task_key == 'read') {
                $giveType = $ubp::read;
            } else {
                return errJson('领取失败，任务未定义');
            }
            $ubp->givePoint($this->uid, $task['point'], $giveType);
        } elseif ($task['state'] == 2) {
            return errJson('请勿重复领取');
        } else {
            return errJson('领取失败，任务未完成');
        }
        return sucJson();
    }


    /**
     * 获取任务信息
     * @param $key
     * @return array|mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function getTaskInfo($key)
    {
        $where[] = ['quick_id', '=', $this->quickAppId];
        if ($this->user->agent_id) {
            $where[] = ['manage_id', '=', $this->user->agent_id];
        } else {
            $where[] = ['manage_id', '=', 0];
        }
        $myTaskData = TaskConfig::where($where)->value('task_data');
        $defaultTemplate = TaskConfig::defaultTemplate($this->quickAppId);
        $myTaskData = json_decode($myTaskData, true);
        $data = [];
        if ($myTaskData) {
            foreach ($defaultTemplate as $k => $v) {
                if (isset($myTaskData[$k])) {
                    $data[$k] = $myTaskData[$k];
                } else {
                    $data[$k] = $v;
                }
            }
        } else {
            $data = $defaultTemplate;
        }
        $task = null;
        foreach ($data as $k => $v) {
            if ($k == $key) {
                $task = $v;
                $task['state'] = $this->getTaskState($key, $v);
            }
        }
        return $task;
    }

    /**
     * 签到详情
     * @return \think\response\Json
     */
    public function signInfo()
    {
        $today = date('Y-m-d');
        $ubp = $this->getUbp();
        $logic = new TaskLogic();
        /**查看今日有无签到*/
        $todaySign = $ubp->where('uid', $this->uid)->where('give_type', $ubp::sign)->order("date desc")->find();
        if (!$todaySign || $todaySign['date'] < $today) {
            $data['today_status'] = 0;
        } else {
            $data['today_status'] = 1;
        }
        $qa = QuickApp::get($this->quickAppId);
        /**查看当前日期坐标*/
        $data['today_index'] = $this->getSignIndex($qa)['index'];
        if ($this->user->agent_id) {
            $manage_id = $this->user->agent_id;
        } else {
            $manage_id = 0;
        }
        $data['template'] = $logic->signTemplate($qa, $manage_id);
        foreach ($data['template'] as $k => $v) {
            if ($k < $data['today_index']) {
                $data['template'][$k]['status'] = 1;
            } elseif ($k == $data['today_index'] && $data['today_status'] == 1) {
                $data['template'][$k]['status'] = 1;
            } else {
                $data['template'][$k]['status'] = 0;
            }
        }
        return sucJson($data);
    }


    /**
     * 获取当天日期签到天数坐标
     * @param $qa
     * @return mixed
     */
    private function getSignIndex($qa)
    {
        $dayCount = $qa->info->sign_max;
        $ubp = $this->getUbp();
        /**查看当前日期坐标*/
        $yesterday = date("Y-m-d", strtotime("-1 day"));
        $yesterdayDate = $ubp->where('uid', $this->uid)->where('give_type', $ubp::sign)->where("date", $yesterday)->find();
        $continuousDays = 1;
        if ($yesterdayDate) {
            $continuousDays = $yesterdayDate['continuous_days'] + 1;
            $remainder = $continuousDays % $dayCount; // 取余
            if ($remainder == 0){
                $today_index  = $dayCount;
            }else{
                $today_index = $remainder;
            }
        } else {
            $today_index = 1;
        }
        $res['index'] = $today_index;
        $res['continuousDays'] = $continuousDays;
        return $res;
    }

    /**
     * 签到
     * @return \think\response\Json
     */
    public function signIn()
    {
        $logic = new TaskLogic();
        $ubp = $this->getUbp();
        $where[] = ['uid', '=', $this->uid];
        $where[] = ['give_type', '=', $ubp::sign];
        $where[] = ['date', '=', date("Y-m-d")];
        $todaySign = $ubp->where($where)->find();
        if (!$todaySign) {
            if ($this->user->agent_id) {
                $manage_id = $this->user->agent_id;
            } else {
                $manage_id = 0;
            }
            $qa = QuickApp::get($this->quickAppId);
            $config = $logic->signTemplate($qa, $manage_id);
            $indexRes = $this->getSignIndex($qa);
            $index = $indexRes['index'];
            $continuousDays = $indexRes['continuousDays'];
            $point = $config[$index]['point'];
            $ubp->givePoint($this->uid, $point, $ubp::sign, $continuousDays);
            return sucJson();
        } else {
            return errJson('请勿重复签到');
        }
    }
}